"use strict";

import { sourcecode_location } from "./sourcecode_base.mjs";
import { token, token_types } from "./tokenize.mjs";

class check_result {
    /**
     *
     * @param {string} check_name 
     * @param {boolean} success success?
     * @param {string} info human readable infomation
     * @param {sourcecode_location} location location
     * @param {int} code machine readable code
     */
    constructor(check_name, success = true, info = "", location = null, code = 0) {
        this.check_name = check_name;
        this.success = success;
        this.info = info;
        this.location = location;
        this.code = code;
    }
}

/**
 *
 * @param {token[]} tokens
 * @returns {check_result[]}
 */
function check_bracket_pair(tokens) {
    let check_name = "check_bracket_pair";

    let r = [];
    let stack = [];

    for (let i of tokens) {
        if (i.type == token_types.left_bracket) {
            stack.push(i);
        }
        else if (i.type == token_types.right_bracket) {
            if (stack.length > 0) {
                stack.pop(i);
            }
            else {
                r.push(new check_result(check_name, false, "unpaired right racket", new sourcecode_location(i.line, i.column)));
            }
        }
    }

    if (stack.length == 0 && r.length == 0) {
        r.push(new check_result(check_name, true, "brackets pair check passed"));
    } else if (stack.length > 0) {
        while (stack.length > 0) {
        let x = stack.pop();
        if (x.type == token_types.left_bracket) {
            r.push(new check_result(check_name, false, "unpaired left racket", new sourcecode_location(x.line, x.column)));
        } else if (x.type == token_types.right_bracket) {
            r.push(new check_result(check_name, false, "unpaired right racket", new sourcecode_location(x.line, x.column)));
            }
        }
    }

    return r;
}

/**
 * 
 * @param {token[]} tokens 
 * @returns {check_result[]}
 */
export function lex_check(tokens) {
    let results = [];

    let chain_func = [check_bracket_pair];

    for (let i of chain_func) {
        results = results.concat(i(tokens));
    }

    return results;
}